<template>
  <div class="meter-device-box">
    <el-form ref="form" :model="formData" :rules="rules" label-width="140px">
      <template v-for="(item, index) in formList">
        <el-form-item
          :key="`${item.prop}${index}`"
          :style="item.itemStyle || {}"
          :label="item.name"
          :prop="item.prop"
          :class="item.itemClass"
        >
          <el-select
            v-if="item.prop === 'readMeterType'"
            v-model="formData.meterType"
            style="width: 50%"
            @change="handlerSelectMeterType"
          >
            <template v-for="option in meterTypeOptions">
              <el-option
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </template>
          </el-select>
          <component
            :is="item.componentType || 'el-input'"
            v-if="item.prop && item.prop !== 'deviceId'"
            v-model="formData[item.prop]"
            :style="item.selectStyle || {}"
            :clearable="true"
            :class="item.class"
            v-bind="item.attrConfig || {}"
            @change="handlerSelectData(item)"
          >
            <template v-for="option in item.optionList">
              <el-option
                :key="option.code"
                :label="option.name"
                :value="option.code"
                :disabled="option.disabled"
              />
            </template>
          </component>
          <div v-else-if="item.prop === 'deviceId'">
            <el-button @click="showDeviceParameterDialog" type="text">+设备参数
            </el-button>
            <div>{{ formData.modelName }}</div>
          </div>

        </el-form-item>
      </template>
    </el-form>
    <el-dialog title="设备参数" :visible.sync="deviceParameterDialog" width="20%" :modal="false" top="10%"
               v-loading="deviceParameterDialogLoading">
      <el-row style="padding-bottom: 10px">
        <el-col :span="4" class="device-param-label required">所属项目:</el-col>
        <el-col :span="20">
          <el-select v-model="formData.deviceParamProjectId" placeholder="所属项目" style="width: 100%"
                     @change="deviceParamProjectChange">
            <el-option v-for="item in formList[5].optionList" :key="item.value" :value="item.value"
                       :label="item.label"></el-option>
          </el-select>
        </el-col>
      </el-row>
      <el-row style="padding-bottom: 10px">
        <el-col :span="4" class="device-param-label">所属场景:</el-col>
        <el-col :span="20">
          <el-cascader v-model="formData.deviceParamSceneInfo" :options="deviceParamSceneList"
                       placeholder="请选择所属场景" clearable style="width: 100%" @change="deviceParamChange"
                       :props="{ checkStrictly: true }" />
        </el-col>
      </el-row>
      <el-row style="padding-bottom: 10px">
        <el-col :span="4" class="device-param-label required">产品类型:</el-col>
        <el-col :span="20">
          <el-select v-model="formData.deviceParamProductTypeId" placeholder="产品类型"
                     @change="deviceParamChange" style="width: 100%">
            <el-option v-for="item in formList[11].optionList" :key="item.value" :value="item.value"
                       :label="item.label"></el-option>
          </el-select>
        </el-col>
      </el-row>
      <el-row style="padding-bottom: 10px">
        <el-col :span="4" class="device-param-label required">设备:</el-col>
        <el-col :span="20">
          <el-select v-model="formData.deviceId" placeholder="设备" style="width: 100%" @change="deviceChangeHandler">
            <el-option v-for="item in deviceList" :key="item.id" :value="item.id" :label="item.deviceName"></el-option>
          </el-select>
        </el-col>
      </el-row>
      <el-table v-loading="paramTabLoading" :data="modelList">
        <el-table-column width="80">
          <template #default="scope">
            <el-radio class="radio" v-model="formData.modelId" :label="scope.row.id"><span></span></el-radio>
          </template>
        </el-table-column>
        <el-table-column prop="modelName" label="参数名称" />
        <el-table-column prop="modelTag" label="标识符" />
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="() =>　this.deviceParameterDialog = false">取 消</el-button>
        <el-button type="primary" @click="objectDialogConfirmHandler">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { dictMixin } from '@/mixin/dict'
import api from '@/api/apis/sceneRoom'
import { parseSceneData, parseToSceneInfo, sceneInfoToParam } from '@/utils/scene-data'
import sceneRoom from '@/api/apis/sceneRoom'

export default {
  name: 'AddMeterDevice',
  mixins: [dictMixin],
  props: {
    // 请求参数
    requestParams: {
      type: Object,
      default: () => ({})
    },
    // 弹窗数据
    popData: {
      type: Object,
      default: () => ({})
    },
    // 弹窗配置
    popConfig: {
      type: Object,
      default: () => ({})
    },
    // 弹窗取消
    close: {
      type: Boolean,
      default: false
    },
    // 弹窗确认
    confirm: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isAdd: true,
      deviceParameterDialog: false,
      deviceParameterDialogLoading: false,
      paramTabLoading: false,
      meterTypeOptions: [],
      modelList: [],
      formData: {
        meterType: '',
        sceneInfo: []
      },
      deviceList: [],
      deviceParamSceneList: [],
      formList: [
        {
          name: '设备编码',
          prop: 'deviceCode',
          attrConfig: { placeholder: '请输入设备编码' }
        },
        {
          name: '设备名称',
          prop: 'deviceName',
          attrConfig: { placeholder: '请输入设备名称' }
        },
        {
          name: '设备类型',
          prop: 'deviceType',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择设备类型',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.meterDevice.deviceType',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '当前状态',
          prop: 'deviceStatus',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择当前状态',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.meterDevice.deviceStatus',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '是否重点关注设备',
          prop: 'isFocus',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'dictList',
          selectParams: {
            codeList: ['ecp-admin.device.isFocus']
          },
          attrConfig: {
            placeholder: '请选择是否重点关注设备',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.device.isFocus',
            nameProp: 'label',
            codeProp: 'value'
          },
          style: { width: '100%' }
        },
        {
          name: '所属项目',
          prop: 'sceneProjectId',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'SceneProjectSelected'
          },
          attrConfig: {
            placeholder: '请选择所属项目',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '所属场景',
          prop: 'sceneInfo',
          componentType: 'el-cascader',
          attrConfig: {
            placeholder: '请选择所属场景',
            props: {
              checkStrictly: true
            },
            options: []
          }
        },
        {
          name: '读表类型',
          prop: 'readMeterType',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择读表类型',
            disabled: true,
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.meterDevice.readMeterType',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '50%' }
        },
        {
          name: '能耗类型',
          prop: 'energyTypeId',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'EnergyConsumptionTypeSelected'
          },
          attrConfig: {
            placeholder: '请选择能耗类型',
            disabled: false,
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '读表标识',
          prop: 'readMeterTag',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择读表标识',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.meterDevice.readMeterTag',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '统计类型',
          prop: 'staticsType',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'MeterDeviceStaticsType'
          },
          attrConfig: {
            placeholder: '请选择统计类型',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        },
        {
          name: '统计产品类型',
          prop: 'productTypeId',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'ProductTypeSelected'
          },
          attrConfig: {
            placeholder: '请选择统计产品类型',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          style: { width: '100%' }
        },
        {
          name: '关联设备参数',
          prop: 'deviceId'
        },
        // {
        //   name: '用途',
        //   prop: 'purpose',
        //   attrConfig: {
        //     placeholder: '请输入用途'
        //   }
        // },
        {
          name: '启用状态',
          prop: 'status',
          componentType: 'el-select',
          optionList: [],
          attrConfig: {
            placeholder: '请选择启用状态',
            options: []
          },
          dataProp: {
            keyProp: 'ecp-admin.meterDevice.status',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '100%' }
        }
      ]
    }
  },
  computed: {
    rules() {
      return {
        deviceCode: [{ required: true, message: '请输入设备编码', trigger: 'blur' }],
        deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
        deviceType: [{ required: true, message: '请选择设备类型', trigger: 'blur' }],
        deviceStatus: [{ required: true, message: '请选择当前状态', trigger: 'blur' }],
        sceneProjectId: [{ required: true, message: '请选择所属项目', trigger: 'blur' }],
        sceneInfo: [{ required: false, message: '请选择所属场景', trigger: 'blur' }],
        readMeterType: [{ required: false, message: '请选择读表类型', trigger: 'blur' }],
        productTypeId: [{ required: true, message: '请选择产品类型', trigger: 'blur' }],
        energyTypeId: [{ required: true, message: '请选择能源类型', trigger: 'blur' }],
        readMeterTag: [{ required: true, message: '请选择读表标识', trigger: 'blur' }],
        purpose: [{ required: true, message: '请输入用途', trigger: 'blur' }],
        status: [{ required: true, message: '请选择启用状态', trigger: 'blur' }]
      }
    }
  },
  watch: {
    popData: {
      async handler(data) {
        const { popType } = this.popConfig
        const dataId = ['add'].includes(popType) ? '' : data.id
        this.isAdd = !dataId
        const formData = Object.assign({}, data)
        if (data.sceneProjectId) {
          // 查询场景选择的数据
          await this.getRoomList(data.sceneProjectId)
        }
        formData.sceneInfo = parseToSceneInfo(data)
        const res = this.formData.deviceId != null && this.formData.modelId != null && this.formData.modelName == null
        if (res) {
          this.$api.meterDevice.deviceModel(this.formData.deviceId).then(response => {
            this.formData.modelName = response.data.find(item => item.id === this.formData.modelId)?.modelName
          })
        }
        this.formData = formData
        this.$set(this.formData, 'sceneInfo', formData.sceneInfo)
      },
      deep: true,
      immediate: true
    },
    confirm() {
      const sceneInfo = sceneInfoToParam(this.formData.sceneInfo)
      const params = {
        ...(this.formData || {}),
        ...sceneInfo
      }
      this.submit(params)
    }
  },
  created() {
    /** 获取字典数据 */
    this.getDictData()
  },
  methods: {
    deviceParamProjectChange(sceneProjectId) {
      this.formData.deviceParamSceneInfo = []
      api.queryRoomList({
        sceneProjectId,
        sortColumn: 'floorName',
        sortOrder: 'asc'
      }).then(res => {
        this.deviceParamSceneList = parseSceneData(res.data)
        this.deviceParamChange()
      })
    },
    deviceParamChange() {
      const { deviceParamProjectId, deviceParamSceneInfo, deviceParamProductTypeId } = this.formData
      if (deviceParamProjectId && deviceParamProductTypeId) {
        const sceneEdificeId = deviceParamSceneInfo != null && deviceParamSceneInfo.length > 0 ? deviceParamSceneInfo[0] : null
        const sceneFloorId = deviceParamSceneInfo != null && deviceParamSceneInfo.length > 1 ? deviceParamSceneInfo[1] : null
        const sceneRoomId = deviceParamSceneInfo != null && deviceParamSceneInfo.length > 2 ? deviceParamSceneInfo[2] : null
        this.$api.device.queryList({
          sceneProjectId: deviceParamProjectId,
          sceneEdificeId: sceneEdificeId,
          sceneFloorId: sceneFloorId,
          sceneRoomId: sceneRoomId,
          productTypeId: deviceParamProductTypeId,
          page: 1,
          limit: 500
        }).then(response => {
          this.deviceList = response.data.records
        }).finally(() => this.deviceParameterDialogLoading = false)
        if (this.formData.id != null && this.formData.deviceId != null) {
          this.deviceChangeHandler(this.formData.deviceId)
        }
      } else {
        this.deviceList = []
      }
    },
    objectDialogConfirmHandler() {
      this.formData.modelName = this.modelList.find(item => item.id === this.formData.modelId)?.modelName
      this.deviceParameterDialog = false

    },
    deviceChangeHandler(deviceId) {
      this.paramTabLoading = true
      this.$api.meterDevice.deviceModel(deviceId).then(response => {
        this.modelList = response.data
      }).finally(() => this.paramTabLoading = false)
    },
    async showDeviceParameterDialog() {
      if (this.formData.deviceId != null && this.formData.deviceParamProjectId == null) {
        const deviceInfoRes = await this.$api.device.detail({ id: this.formData.deviceId })
        const deviceInfo = deviceInfoRes.data
        if(deviceInfo != null) {
          this.formData.deviceParamProjectId = deviceInfo.sceneProjectId
          await this.deviceParamProjectChange(this.formData.deviceParamProjectId)
          this.formData.deviceParamProductTypeId = deviceInfo.productTypeId
          const sceneInfo = []
          if (deviceInfo.sceneEdificeId != null) {
            sceneInfo.push(deviceInfo.sceneEdificeId)
          }
          if (deviceInfo.sceneFloorId != null) {
            sceneInfo.push(deviceInfo.sceneFloorId)
          }
          if (deviceInfo.sceneRoomId != null) {
            sceneInfo.push(deviceInfo.sceneRoomId)
          }
          this.formData.deviceParamSceneInfo = sceneInfo
        }else {
          delete this.formData.deviceId;
        }
      }
      this.deviceParameterDialog = true
      this.deviceParamChange()

    },
    /**
     * change事件
     */
    handlerSelectData(config) {
      const Ref = this.$refs[config.prop]
      if (Ref && config.isClosePop) {
        Ref.dropDownVisible = false
      }
      const value = this.formData[config.prop]
      if (config.prop === 'sceneProjectId') {
        // 选择项目后加载场景数据
        this.getRoomList(value, true)
      }
      // if (config.prop === 'readMeterType'){
      //   // 选择读表类型后，禁用某项用途
      //   this.disablePurpose(value)
      // }
      if (config.prop === 'sceneInfo') {
        if (value == null || value.length === 0) {
          this.formData.sceneInfoName = null
        }
        this.formData.sceneEdificeId = value.length > 0 ? value[0] : null
        this.formData.sceneFloorId = value.length > 1 ? value[1] : null
        this.formData.sceneRoomId  = value.length > 2 ? value[2] : null

      }
      this.$forceUpdate()
    }
    ,
    handlerSelectMeterType(value, resetValue) {
      this.disableReadMeterType(value, resetValue)
      const item = this.meterTypeOptions.find(o => o.value === value)
      this.autoSelectEnergyType(item.label)
    }
    ,
    /**
     * 禁用读表类型选项
     */
    disableReadMeterType(meterType, resetValue = true) {
      const item = this.formList[7]
      if (item.optionList.length > 0) {
        item.attrConfig.disabled = !meterType
        item.optionList.map(option => {
          option.disabled = !option.value.startsWith(meterType)
        })
        if (resetValue) {
          this.formData.readMeterType = ''
        }
        this.$set(this.formList, 7, { ...item })
      }
    }
    ,
    /**
     * 管理自动选择能耗类型
     */
    autoSelectEnergyType(meterTypeName) {
      const item = this.formList[8]
      console.log(item, meterTypeName)
      const energyType = item.optionList.find(option => meterTypeName.includes(option.name))
      this.formData.energyTypeId = energyType.code || ''
    }
    ,
    /**
     * 提交
     */
    submit(params) {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          const res = await this.$api.meterDevice[
            this.isAdd ? 'add' : 'update'
            ](params)
          if (Number(res.code) === 1000) {
            this.$message.success(`${this.isAdd ? '新增' : '编辑'}成功！`)
            this.$emit('onFinish', 'meter-device-add')
          }
        }
      })
    }
    ,
    /**
     * 获取空间列表
     * @param sceneProjectId
     */
    async getRoomList(sceneProjectId, reset = false) {
      const res = await api.queryRoomList({
        sceneProjectId,
        sortColumn: 'floorName',
        sortOrder: 'asc'
      })
      const roomList = parseSceneData(res.data)
      const item = this.formList[6]
      item.attrConfig.options = roomList
      this.$set(this.formList, 6, { ...item })
      if (reset) {
        this.formData.sceneInfo = []
      }
    }
    ,
    /**
     * 获取字段数据
     */
    async getDictData() {
      const res = await this.$api.dictList({
        codeList: [
          'ecp-admin.meterDevice.deviceType',
          'ecp-admin.meterDevice.deviceStatus',
          'ecp-admin.meterDevice.meterType',
          'ecp-admin.meterDevice.readMeterType',
          'ecp-admin.meterDevice.readMeterTag',
          'ecp-admin.device.isFocus',
          'ecp-admin.meterDevice.status'
        ]
      })
      this.meterTypeOptions = res.data['ecp-admin.meterDevice.meterType']
      for (let i = 0; i < this.formList.length; i++) {
        const item = this.formList[i]
        const { keyProp } = item.dataProp || {}
        if (keyProp) {
          item.optionList = res.data[keyProp].map(dict => {
            dict.name = dict.label
            dict.code = dict.value
            return dict
          })
          if (i === 6 && this.formData.meterType) {
            this.handlerSelectMeterType(this.formData.meterType, false)
          }
          this.$set(this.formList, i, { ...item })
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.meter-device-box {
  color: #333;
  padding: 0 20px;

  ::v-deep .el-form {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;

    .el-form-item {
      width: calc(50% - 10px);

      &.width100p {
        width: 100%;
      }

      .el-form-item__label {
        color: #666;
        font-size: 14px;
      }

      &.form-sub-title {
        width: 100%;

        .el-form-item__label {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          font-weight: bold;
          color: #333;
          font-size: 16px;
          line-height: 1;

          &::before {
            content: '';
            display: inline-block;
            width: 4px;
            height: 15px;
            background-color: #00858d;
            margin-right: 5px;
          }
        }
      }
    }

    .el-select,
    .el-cascader {
      width: 100%;
    }
  }

  .device-param-label {
    text-align: left;
    line-height: 32px;
    font-size: 14px;
    font-weight: 600;
  }

  .device-param-label.required::before {
    content: '*';
    color: #F56C6C;
    margin-right: 4px;
  }
}
</style>
